
/*
 * 版权声明 (c) 2025 XXX科技有限公司
 *
 * 本软件及其相关文档文件受版权保护。未经版权所有者明确书面许可，任何单位或个人不得
 * 以任何形式复制、传播、修改、出售、出租、反向工程、反编译或利用本软件的任何部分。
 *
 * 对于任何违反本声明的行为，版权所有者保留追究法律责任的权利。
 */

#ifndef __EVENT_H__
#define __EVENT_H__
#include <iostream>
#include <unordered_map>
#include <vector>
#include <functional>
#include <typeindex> // 用于获取类型信息
#include <future>    // 用于保存异步任务结果
#include <memory>
#include <mutex>

using namespace std;

// FIXME: 「Feature」事件总线
class EventBus {
private:
	unordered_map<type_index, vector<function<void(const void *)>>> subscribers;
	mutex                                                           mtx;

public:
	// 订阅事件
	template<typename T>
	size_t Subscribe(function<void(const T &)> handler) {
		lock_guard<mutex> lock(mtx);
		type_index        type    = typeid(T);
		auto              wrapper = [handler](const void *event) { handler(*static_cast<const T *>(event)); };
		subscribers[type].push_back(wrapper);
		return subscribers[type].size() - 1;
	}

	// 取消订阅
	template<typename T>
	bool Unsubscribe(size_t token) {
		lock_guard<mutex> lock(mtx);
		type_index        type = typeid(T);

		if (!subscribers.count(type) || token >= subscribers[type].size()) return false;
		subscribers[type][token] = nullptr;
		return true;
	}

	template<typename T>
	void PublishAsync(const T &event) {
		vector<function<void(const void *)>> activeHandlers;
		{
			lock_guard<mutex> lock(mtx);
			type_index        type = typeid(T);
			if (!subscribers.count(type)) return;

			// 仅收集非空handler
			for (const auto &handler: subscribers[type]) {
				if (handler) {
					activeHandlers.push_back(handler);
				}
			}
		}

		// 用shared_ptr保存事件副本，确保异步任务中生命周期有效
		auto                 eventPtr = make_shared<T>(event);
		vector<future<void>> futures; // 保存future对象
		for (const auto &handler: activeHandlers) {
			futures.push_back(async(launch::async, [handler, eventPtr]() {
				handler(eventPtr.get()); // 使用共享指针的地址，避免引用失效
			}));
		}
	}
};

#endif // __EVENT_H__